package com.yanghui.dtracing.plugin.spring;

import com.yanghui.dtracing.core.match.ClassMatch;
import com.yanghui.dtracing.core.match.IndirectMatch;
import com.yanghui.dtracing.core.plugin.AbstractClassEnhancePluginDefine;
import com.yanghui.dtracing.core.plugin.IInstanceMethodInterceptPoint;
import net.bytebuddy.description.annotation.AnnotationDescription;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher;
import net.bytebuddy.matcher.ElementMatchers;

public class SpringDefinition extends AbstractClassEnhancePluginDefine {

    private static final String SERVICE = "org.springframework.stereotype.Service";
//    private static final String COMPONENT = "org.springframework.stereotype.Component";
    private static final String RESTONTROLLER = "org.springframework.web.bind.annotation.RestController";

    @Override
    public ClassMatch enhanceClass() {
        return new IndirectMatch() {
            @Override
            public ElementMatcher.Junction buildJunction() {
                return ElementMatchers.isAnnotatedWith(ElementMatchers.named(SERVICE))
                        .or(ElementMatchers.isAnnotatedWith(ElementMatchers.named(RESTONTROLLER)))
                        .and(ElementMatchers.not(ElementMatchers.isAnnotation()));
            }

            @Override
            public boolean isMatch(TypeDescription typeDescription) {
                for(AnnotationDescription  annotationDescription : typeDescription.getInheritedAnnotations()){
                    String name = annotationDescription.getAnnotationType().getName();
                    if(SERVICE.equals(name) || RESTONTROLLER.equals(name)){
                        return true;
                    }
                }
                return false;
            }
        };
    }

    @Override
    public IInstanceMethodInterceptPoint[] buildInstanceMethodInterceptPoints() {
        return new IInstanceMethodInterceptPoint[]{
                new IInstanceMethodInterceptPoint(){
                    @Override
                    public ElementMatcher<MethodDescription> buildMethodsMatcher() {
                        return ElementMatchers.not(ElementMatchers.isStatic());
                    }

                    @Override
                    public String methodInterceptor() {
                        return "com.yanghui.dtracing.plugin.spring.SpringInstanceMethodAroundInterceptor";
                    }
                }
        };
    }
}
